package org.yunai.yfserver.plugin.mina.service;

import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.yunai.yfserver.common.LoggerFactory;
import org.yunai.yfserver.message.ISessionMessage;
import org.yunai.yfserver.message.sys.SessionClosedMessage;
import org.yunai.yfserver.message.sys.SessionOpenedMessage;
import org.yunai.yfserver.plugin.mina.session.AbstractMinaSession;
import org.yunai.yfserver.server.IMessageProcessor;

/**
 * Mina的IoHandler基类
 * User: yunai
 * Date: 13-3-26
 * Time: 下午10:55
 */
public abstract class AbstractMinaIoHandler<S extends AbstractMinaSession> implements IoHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerFactory.Logger.game, AbstractMinaIoHandler.class);

    protected static final AttributeKey SESSION_ATTR_ISESSION = new AttributeKey(AbstractMinaIoHandler.class, "ISESSION");

    protected IMessageProcessor msgProcessor;

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        LOGGER.info("[sessionOpened] [session open:{}].", session.getId());

        AbstractMinaSession minaSession = createSession(session);
        session.setAttribute(SESSION_ATTR_ISESSION, minaSession);

        msgProcessor.put(new SessionOpenedMessage<S>());
    }

    @Override
    @SuppressWarnings("unchecked")
    public void messageReceived(IoSession session, Object message) throws Exception {
        if (!(message instanceof ISessionMessage)) {
            return;
        }
        ISessionMessage msg = (ISessionMessage) message;

        AbstractMinaSession minaSession = (AbstractMinaSession) session.getAttribute(SESSION_ATTR_ISESSION);
//        TODO 看情况是否要判断minaSession为空，若为空，则session.close();

        msg.setSession(minaSession);
        msgProcessor.put(msg);
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        LOGGER.info("[sessionClosed] [session close:{}].", session.getId());

        AbstractMinaSession minaSession = (AbstractMinaSession) session.getAttribute(SESSION_ATTR_ISESSION);
        if (minaSession != null) {
            session.removeAttribute(minaSession);
        }

        msgProcessor.put(new SessionClosedMessage<S>());
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        cause.printStackTrace();

        // TODO 在研究下
    }


    public void setMsgProcessor(IMessageProcessor msgProcessor) {
        this.msgProcessor = msgProcessor;
    }

    /**
     * 由子类实现的
     *
     * @return
     */
    protected abstract S createSession(IoSession session);
}
